/*
********************************************************************************
* Copyright (C) 2021, xiang.D <dx_65535@163.com>.
* All right reserved.
*
* File Name   : invoker.cc
* Author      :
* Version     : V1.0
* Description :
* Journal     : 2021-11-27 init v1.0
* Brief       : Blog: https://blog.csdn.net/qq_38750572?spm=1001.2014.3001.5343
* Others      :
********************************************************************************
*/

#include <stdio.h>
#include "invoker.h"
#include "led.h"
#include "motor.h"

using namespace std;

#define INVOKE_LOGI(fmt, args...) printf("Invoke: I: %d " fmt, __LINE__, ##args)
#define INVOKE_LOGD(fmt, args...) printf("Invoke: D: %d " fmt, __LINE__, ##args)
#define INVOKE_LOGW(fmt, args...) printf("Invoke: W: %d " fmt, __LINE__, ##args)
#define INVOKE_LOGE(fmt, args...) printf("Invoke: E: %d " fmt, __LINE__, ##args)

CInvoker::CInvoker()
{
    INVOKE_LOGI("Init Invoker!\n");
    Init();
}

CInvoker::~CInvoker()
{

}

CInvoker* CInvoker::GetInstance()
{
    static CInvoker mObj;
    return &mObj;
}

int CInvoker::Init()
{
    int ret, index = 0;
    static CLed   *theLed   = CLed::GetInstance();
    static CMotor *theMotor = CMotor::GetInstance();

    // 清空命令表
    mCmdTable.clear();

    // 注册命令列表
    ret = CmdRegister(CMD_LED,    theLed);
    if (ret != 0) {
        INVOKE_LOGE("Register 0x%x failed!\n", CMD_LED);
    }

    ret = CmdRegister(CMD_MOTOR,  theMotor);
    if (ret != 0) {
        INVOKE_LOGE("Register 0x%x failed!\n", CMD_MOTOR);
    }

    return 0;
}

int CInvoker::CmdRegister(ECmdType cmdType, CCmd *pCmd)
{
    auto it = mCmdTable.find(cmdType);

    if (it == mCmdTable.end()) {
        mCmdTable.insert(std::pair<ECmdType, CCmd *>(cmdType, pCmd));
        return 0;
    }
    else {
        INVOKE_LOGW("Cmd array: 0x%x busy!\n", cmdType);
        return -1;
    }
}

int CInvoker::Invoke(ECmdAction cmd)
{
    int ret = -1;
    ECmdType index = (ECmdType)(cmd >> CMD_BYTES);

    auto it = mCmdTable.find(index);
    if (it == mCmdTable.end()) {
        INVOKE_LOGE("No this cmd: 0x%x\n", cmd);
        ret = -1;
    }
    else {
        ret = mCmdTable[index]->ProcessMsg(cmd);
    }

    return ret;
}
